﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed

#pragma once
#include "GcmpRenderingInterface.h"
#include "GcmpApiDeclaration.h"
#include "ISkyOptions.h"
#include "ISkyOptionsDeprecated.h"
#include "IShadowOptions.h"
#include "IViewHouseOptions.h"
#include "NdbDataSchema.h"

namespace gcmp
{
    class IViewShipOptions;

    /// \brief 自动LOD层级
    SERIALIZABLE_ENUM_CLASS(AutoLodLevel)
    {
        Hide,       ///隐藏
        Curve2d,    ///二维线替代
        Box         ///局部空间包围盒替代
    };

    /// \brief 批次合并策略
    enum class RenderPatchCombineStrategy : int32_t
    {
        Maximum = 0,        ///< 最大化合并，只要状态集一样就合并
        SortAdjacency = 1,  ///< 按照图元优先级排序,相邻图元且状态集相同就合并
    };

    /// \brief 画布选项设置
    class GCMP_RENDERING_INTERFACE_EXPORT ICanvasOptions
    {
    public:
        virtual ~ICanvasOptions();

        /// \brief 得到ViewShip选项设置
        /// \return 
        virtual IViewShipOptions* GetViewShipOptions() = 0;

        /// \brief 显示坐标系
        virtual void ShowViewAxis() = 0;

        /// \brief 隐藏坐标系
        virtual void HideViewAxis() = 0;

        /// \brief 坐标系是否显示
        /// \return 是否显示
        virtual bool IsViewAxisVisible() const = 0;

        /// \brief 设置是否采用大模型优先显示策略
        /// \param bUse 是否使用
        virtual void EnableGroupedRendering(bool bUse) = 0;

        /// \brief 是否使用大模型优先显示策略
        /// \return 是否使用
        virtual bool IsGroupedRenderingEnabled() const = 0;

        /// \brief 设置大模型优先显示策略显示的模型数
        /// \return 设置成功返回true，否则返回失败
        /// \note 设置范围[1,20000]
        virtual bool SetGroupedRenderingDrawNumber(int drawNumber) = 0;

        /// \brief 设置是否使用全屏抗锯齿FullSceneAntiAliasing
        ///
        ///此接口是全局开关，控制是否开启抗锯齿。
        ///ModelViewDisplayOptions::StatesetMultiSampleEnabled控制状态集的抗锯齿开关。
        /// \param enable 是否使用
        virtual void EnableFullSceneAntiAliasing(bool enable) = 0;

        /// \brief 是否使用全屏抗锯齿
        /// \return 是否使用
        virtual bool IsFullSceneAntiAliasingEnabled() const = 0;

        /// \brief 显示渲染信息面板
        /// \return 
        virtual void ShowRenderInformationPanel() = 0;

        /// \brief 隐藏渲染信息面板
        /// \return 
        virtual void HideRenderInformationPanel() = 0;

        /// \brief 设置是否启用VBO渲染选项
        /// \param enable 是否使用VBO
        /// \return true表示设置成功，false表示支持vbo，设置失败
        virtual bool EnableVbo(bool enable) = 0;

        /// \brief 是否使用VBO
        /// \return 启用VBO返回true,否则返回false
        virtual bool IsVboEnabled() const = 0;

        /// \brief 设置LOD层级对应的像素误差，当前图元在屏幕上投影包围球的直径的像素值
        /// \param lodLevel Lod层级
        /// \param pixel   像素值
        /// \return
        virtual void SetAutoLodThreshold(AutoLodLevel lodLevel,double pixel) = 0;

        /// \brief 获取Lod各层级对应的像素误差
        /// \param lodLevel Lod层级
        /// \return Lod层级对应的像素值
        virtual double GetAutoLodThreshold(AutoLodLevel lodLevel) const = 0;

        /// \brief 设置是否启用批次合并功能
        ///
        /// 如果有独显，建议在开启该功能前，先开启VBO功能。（ICanvasOptions::EnableVbo）
        /// \param enable为是否开启批次合并功能.
        /// \param renderPatchCombineStrategy为批次合并策略
        /// \return
        virtual void EnableRenderPatchCombine(bool enable , RenderPatchCombineStrategy renderPatchCombineStrategy) = 0;

        /// \brief 设置是否启用批次合并功能
        /// \return
        GCMP_OBSOLETE_API(2021 / 01 / 01, ICanvasOptions::EnableRenderPatchCombine(bool , EnPrimRenderCmbStrategy )) virtual void EnableRenderPatchCombine(bool enable) = 0;

        /// \brief 获取是否启用批次合并功能
        /// \return  启用批次合并功能返回true,否则返回fasle
        virtual bool IsRenderPatchCombineEnabled() const = 0;

        /// \brief 获取批次合并策略
        ///
        /// 获取合并策略前需要开启批次合并功能（EnableRenderPatchCombine），否则返回值没有意义。
        /// \return  返回在使用得批次合并策略
        virtual RenderPatchCombineStrategy GetRenderPatchCombineStrategy() const = 0;

        /// \brief 设置每秒最小帧速
        /// \param minFPS 每秒最小帧速
        /// \return  
        virtual void SetMinFramePerSecond(uint32_t minFPS) = 0;

        /// \brief 获取每秒最小帧速
        /// \return  每秒最小帧速
        virtual uint32_t GetMinFramePerSecond() const = 0;

        /// \brief 设置有限制的漫游缩放功能是否启用
        /// \param bEnableZoomLimit 启用有限制的漫游缩放功能为true
        /// \return
        virtual void SetZoomLimitEnabled(bool bEnableZoomLimit) = 0;

        /// \brief 设置漫游命令允许的最大放大限制，ZoomInLimit代表窗口高度所对应的最小实际尺寸，以毫米为单位，默认值为50毫米
        /// \note 仅仅在正交投影模式下有效
        /// \param[in] fLimit 最大放大限制
        /// \return
        virtual void SetZoomInLimit(float fLimit) = 0;

        /// \brief 获取漫游命令允许的最大放大限制
        /// \note 仅仅在正交投影模式下有效
        /// \return 最大放大限制
        virtual float GetZoomInLimit() const = 0;

        /// \brief 设置漫游命令允许的最大缩小限制，ZoomOutLimit代表窗口高度所对应的最大实际尺寸，以毫米为单位，默认值为1000000毫米
        /// \note 开启LimitedZoomEnabled功能后可以在正交和透视投影下使用
        /// \param[in] fLimit 最大缩小限制
        virtual void SetZoomOutLimit(float fLimit) = 0;

        /// \brief 获取漫游命令允许的最大缩小限制
        /// \note 开启LimitedZoomEnabled功能后可以在正交和透视投影下使用
        /// \return 返回最大缩小限制
        virtual float GetZoomOutLimit() const = 0;

        /// \brief 是否使用自由旋转模式
        /// \return true 自由旋转模式 false 环绕模式
        virtual bool IsFreeRotation() const = 0;

        /// \brief 设置是否使用自由旋转模式
        /// \param[in] isFreeRotation true 自由旋转模式 false 环绕模式
        /// \return
        virtual void SetFreeRotation(bool isFreeRotation) = 0;

        /// \brief 环绕模式旋转时，是否允许上下翻转
        /// \return 是否允许翻转，否的话，z轴只能朝上
        virtual bool IsOrbitalRotationFlippable() const = 0;

        /// \brief 设置环绕模式旋转时，是否允许上下翻转
        /// \param[in] isFlippable 是否允许翻转，否的话，z轴只能朝上
        /// \return
        virtual void SetOrbitalRotationFlippable(bool isFlippable) = 0;

        /// \brief 设置视图是否允许旋转
        /// \param[in] isEnable 是否允许旋转
        /// \return
        virtual void EnableViewRotation(bool isEnable) = 0;

        /// \brief 获取视图是否允许旋转
        /// \return 允许旋转返回true，否则返回false
        virtual bool IsViewRotationEnabled() const = 0;

        /// \brief 获取天空属性
        /// \return 返回ISkyOptions实例的指针
        virtual ISkyOptions* GetSkyOptions() = 0;

        /// \brief 获取阴影属性
        /// \return 返回IShadowOptions实例的指针
        virtual IShadowOptions* GetShadowOptions() = 0;

#pragma warning(push)
#pragma warning(disable: 4996)
        /// \brief 获取天空和阴影属性
        /// \return 返回ISkyOptionsDeprecated实例的指针
        /// \note 该接口后面会被废弃，请避免使用该接口
        GCMP_DEPRECATED_API(2020/08/01) virtual ISkyOptionsDeprecated* GetSkyOptionsDeprecated() = 0;
#pragma warning(pop)

        ///\brief 获取ViewHouse选项设置
        ///\return 返回ViewHouse选项设置
        virtual IViewHouseOptions* GetViewHouseOptions() = 0;
    };
}

